package mr.ali.webvideo.jsSdk;

import mr.ali.webvideo.jsSdk.WechatJsapiSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

@Service
public class WechatServiceImpl implements WechatService {

    private static final Logger logger = LoggerFactory.getLogger(WechatServiceImpl.class);

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private RestTemplate restTemplate;

    // 设置请求超时时间（单位：毫秒）
    private static final int REQUEST_TIMEOUT = 5000;

    // 缓存access_token和jsapi_ticket
    private String accessToken;
    private long accessTokenExpireTime;
    private String jsapiTicket;
    private long jsapiTicketExpireTime;

    @Override
    public WechatJsapiSignature createJsapiSignature(String url) {
        // 1. 获取jsapi_ticket
        String ticket = getJsapiTicket();

        // 2. 生成签名
        String nonceStr = generateNonceStr();
        long timestamp = System.currentTimeMillis() / 1000;

        // 按照微信官方要求拼接字符串
        String str = "jsapi_ticket=" + ticket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;

        // 使用SHA-1进行签名
        String signature = sha1(str);

        // 3. 返回签名数据
        WechatJsapiSignature result = new WechatJsapiSignature();
        result.setAppId(wechatConfig.getAppid());
        result.setTimestamp(timestamp);
        result.setNonceStr(nonceStr);
        result.setSignature(signature);

        return result;
    }

    private String getJsapiTicket() {
        // 检查缓存是否有效
        if (jsapiTicket != null && System.currentTimeMillis() < jsapiTicketExpireTime) {
            return jsapiTicket;
        }

        // 获取access_token
        String accessToken = getAccessToken();

        // 请求jsapi_ticket
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" +
                accessToken + "&type=jsapi";

        try {
            // 先获取原始响应字符串用于调试
            String rawResponse = restTemplate.getForObject(url, String.class);
            logger.debug("微信jsapi_ticket API原始响应: {}", rawResponse);
            
            WechatTicketResponse response = restTemplate.getForObject(url, WechatTicketResponse.class);
            logger.debug("微信jsapi_ticket API解析后响应: {}", response);

            if (response != null && "ok".equals(response.getErrmsg())) {
                jsapiTicket = response.getTicket();
                // 设置过期时间，提前5分钟过期
                jsapiTicketExpireTime = System.currentTimeMillis() + (response.getExpiresIn() - 300) * 1000L;
                logger.info("成功获取jsapi_ticket, 有效期: {}秒", response.getExpiresIn());
                return jsapiTicket;
            } else {
                String errorMsg = "获取jsapi_ticket失败: " + (response != null ? 
                    ("错误信息: " + response.getErrmsg() + ", 错误码: " + response.getErrcode()) : "响应为空");
                logger.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
        } catch (Exception e) {
            logger.error("调用微信jsapi_ticket API异常: {}", e.getMessage(), e);
            throw new RuntimeException("调用微信jsapi_ticket API异常: " + e.getMessage(), e);
        }
    }

    private String getAccessToken() {
        // 检查缓存是否有效
        if (accessToken != null && System.currentTimeMillis() < accessTokenExpireTime) {
            return accessToken;
        }

        // 请求access_token
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
                "&appid=" + wechatConfig.getAppid() +
                "&secret=" + wechatConfig.getSecret();

        try {
            // 先获取原始响应字符串用于调试
            String rawResponse = restTemplate.getForObject(url, String.class);
            logger.debug("微信API原始响应: {}", rawResponse);
            
            WechatTokenResponse response = restTemplate.getForObject(url, WechatTokenResponse.class);
            logger.debug("微信API解析后响应: {}", response);

            if (response != null && response.getAccessToken() != null && response.getErrmsg() == null) {
                accessToken = response.getAccessToken();
                // 设置过期时间，提前5分钟过期
                accessTokenExpireTime = System.currentTimeMillis() + (response.getExpiresIn() - 300) * 1000L;
                logger.info("成功获取access_token, 有效期: {}秒", response.getExpiresIn());
                return accessToken;
            } else {
                String errorMsg = "获取access_token失败: " + (response != null ? 
                    ("错误信息: " + response.getErrmsg() + ", 错误码: " + response.getErrcode()) : "响应为空");
                logger.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
        } catch (Exception e) {
            logger.error("调用微信API异常: {}", e.getMessage(), e);
            throw new RuntimeException("调用微信API异常: " + e.getMessage(), e);
        }
    }

    private String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
    }

    private String sha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            byte[] bytes = digest.digest(str.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(bytes);
        } catch (Exception e) {
            throw new RuntimeException("SHA-1签名失败", e);
        }
    }

    private String bytesToHex(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        for (byte b : bytes) {
            builder.append(String.format("%02x", b));
        }
        return builder.toString();
    }
}